package com.mtw.bbs.common.core.security.context;

import com.mtw.bbs.common.core.security.context.strategy.GlobalSecurityContextHolderStrategy;
import com.mtw.bbs.common.core.security.context.strategy.InheritableThreadLocalSecurityContextHolderStrategy;
import com.mtw.bbs.common.core.security.context.strategy.ThreadLocalSecurityContextHolderStrategy;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Constructor;

public class SecurityContextHolder {

    // 基于ThreadLocal的上下文策略
    public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
    // 基于InheritableThreadLocal的上下文策略
    public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
    // 基于静态字段实现的上下文策略
    public static final String MODE_GLOBAL = "MODE_GLOBAL";
    // 策略配置
    public static final String SYSTEM_PROPERTY = "security.strategy";
    // 使用的策略
    private static String strategyName = System.getProperty(SYSTEM_PROPERTY);
    // 上下文
    private static SecurityContextHolderStrategy strategy;
    // 初始化次数
    private static int initializeCount = 0;

    static {
        initialize();
    }


    /**
     * 清理
     */
    public static void clearContext() {
        strategy.clearContext();
    }


    /**
     * 获取
     */
    public static SecurityContext getContext() {
        return strategy.getContext();
    }


    public static int getInitializeCount() {
        return initializeCount;
    }


    /**
     * 初始化
     */
    private static void initialize() {
        if (StringUtils.isBlank(strategyName)) {
            // 默认基于ThreadLocal的上下文策略
            strategyName = MODE_THREADLOCAL;
        }

        switch (strategyName) {
            case MODE_THREADLOCAL -> strategy = new ThreadLocalSecurityContextHolderStrategy();
            case MODE_INHERITABLETHREADLOCAL -> strategy = new InheritableThreadLocalSecurityContextHolderStrategy();
            case MODE_GLOBAL -> strategy = new GlobalSecurityContextHolderStrategy();
            default -> {
                // 自定义策略，实现SecurityContextHolderStrategy接口的类全路径
                try {
                    Class<?> clazz = Class.forName(strategyName);
                    Constructor<?> customStrategy = clazz.getConstructor();
                    strategy = (SecurityContextHolderStrategy) customStrategy.newInstance();
                } catch (Exception ex) {
                    ReflectionUtils.handleReflectionException(ex);
                }
            }
        }
        initializeCount++;
    }


    /**
     * 设置
     */
    public static void setContext(SecurityContext context) {
        strategy.setContext(context);
    }


    /**
     * 设置策略名称
     */
    public static void setStrategyName(String strategyName) {
        SecurityContextHolder.strategyName = strategyName;
        initialize();
    }


    /**
     * 获取策略
     */
    public static SecurityContextHolderStrategy getContextHolderStrategy() {
        return strategy;
    }


    /**
     * 创建空的上下文
     */
    public static SecurityContext createEmptyContext() {
        return strategy.createEmptyContext();
    }
}
